不曉得大家有沒有覺得前面幾篇的教學文毫無架構可言,但還是可以做到我們要做到的事情,這是最可怕的地方,因為雜亂無序的程式碼在規模越來越大以後會變得十分難維護,就算用 再好的工具都無法拯救無架構的系統 ,如同一名武士,用再好的刀沒有技術地亂砍終究只是下級武士。為了不讓這一切成為惡夢的開端,如果不熟悉這部分的朋友請一定要看接下來的部分,它可以拯救你的!另外,接下來的實作將會以 TodoList 的 API Server 為目標來開發!
MVC 是一種架構的設計方式,我們會先照著 MVC 的思維來設計,但終究要走出自己的道路,來彌補 MVC 架構下的不足,這邊我先埋下伏筆,後面的篇章會再一一揭曉。
我們會採用物件導向的方式做設計,而不是使用 Function Programming,我認為物件導向是比較好被理解的,Function Programming 相對來說比較難閱讀,而且 class 那麼香我一定用爆
檔案管理也是很重要的一門課,會將檔案依照某種特定的規則存放於不同資料夾中,這個分類方式因人而異,也因專案規模而異,大致上有兩種分類模式:職責分類 與 對象分類。
這類型的分類法我認為適合用在 小型專案 以及 共用的功能模組,它是依照該程式的職責類型來做分類,舉例來說,所有 routing 相關的模組歸類於資料夾 routes
當中:
├── src
| ├── index.ts
| └── routes
| ├── app.routing.ts
| └── user.routing.ts
├── package.json
└── tsconfig.json
這類型的分類法我認為適合用在 各種規模的專案,它將程式碼依照模組服務的對象來做分類,這麼說有點抽象,舉例來說,我們將 users
路由下特有的程式都放在這個資料夾:
├── src
| ├── index.ts
| └── users
| ├── user.controller.ts
| └── user.routing.ts
├── package.json
└── tsconfig.json
後續的實作將會以 對象分類為主、職責分類為輔 ,共用的功能模組以職責分類來維護,其餘的依照對象分類的模式來管理。
將本來的專案目錄結構調整成下方的樣子,並清空 src
底下的 index.ts
:
├── src
| ├── index.ts
| ├── environments
| | ├── development.env
| | └── production.env
| └── validators
| ├── index.ts
| └── email.validator.ts
├── package.json
└── tsconfig.json
接著我們再調整一下目錄:
├── src
| ├── index.ts
| ├── app.ts // 新增的檔案
| ├── environments
| | ├── development.env
| | └── production.env
| └── validators
| ├── index.ts
| └── email.validator.ts
├── package.json
└── tsconfig.json
我們會以 index.ts
作為載入點,將 Express App 的應用程式層抽離至 app.ts
,下方為 app.ts
的程式碼:
import express from 'express';
import path from 'path';
import cors from 'cors';
import helmet from 'helmet';
import dotenv from 'dotenv';
export class App {
private app = express();
constructor() {
this.setEnvironment();
this.setHelmet();
this.setCors();
this.registerRoute();
}
// ====================================================================
// @Public Methods
// ====================================================================
public bootstrap(): void {
this.app.listen(process.env.PORT, () => console.log(`API Server is running at port ${ process.env.PORT }.`));
}
// ====================================================================
// @Private Methods
// ====================================================================
private setHelmet(): void {
this.app.use(helmet());
}
private setCors(): void {
this.app.use(cors());
}
private setEnvironment(): void {
dotenv.config({ path: path.resolve(__dirname, `./environments/${ process.env.NODE_ENV }.env`) });
}
private registerRoute(): void {
this.app.get('/', (req, res, next) => res.send('Hello!'));
}
}
App
在建構時即註冊路由,並透過 bootstrap()
啟動 Express App。
最後就是在 index.ts
中使用 App
:
import { App } from './app';
const bootstrap = () => {
const app = new App();
app.bootstrap();
};
bootstrap();
今天主要就是將 Express App 的應用程式層抽離出來作為根節點,既然是整個專案的根節點,勢必就有子節點,這些子節點都會被收斂至根節點,這樣說有點太艱澀難懂了,簡單來說就是將不同層級的路由,透過路由器層的概念來切割,以便管理,那我們要怎麼切割呢?會在下一篇告訴大家。